package com.noovo.comport.server;

import java.util.HashMap;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;

public abstract class ComHelper {
	private Context mContext;
	private final Uri URI_SET = Uri.parse("content://com.noovo.comport.setting/port_in/set");
	private final Uri URI_SEND = Uri.parse("content://com.noovo.comport.setting/port_in/send");
	private final Uri URI_RECEIVE = Uri.parse("content://com.noovo.comport.setting/port_out/receive");

	private HashMap<String, Integer> nameMap = new HashMap<String, Integer>();
	private ComObserver mComObserver;

	private final class ComObserver extends ContentObserver {

		public ComObserver(Handler handler) {
			super(handler);
		}

		@Override
		public void onChange(boolean selfChange, Uri uri) {
			int store_id = Integer.parseInt(uri.getPathSegments().get(3));
			String receive = "receive" + "_" + store_id;
			String[] projection = { "name", receive };
			Cursor cursor = mContext.getContentResolver().query(uri, projection, null, null, null);
			if (cursor != null && cursor.moveToFirst()) {
				String name = cursor.getString(cursor.getColumnIndex("name"));
				byte[] msg = cursor.getBlob(cursor.getColumnIndex(receive));
				cursor.close();
				MessageCall(name, msg);
			}
		}
	}

	abstract void MessageCall(String comName, byte[] message);

	public ComHelper(Context context) {
		mContext = context;
		mComObserver = new ComObserver(new Handler());
		Intent intent = new Intent();
		intent.setClassName("com.noovo.comport", "com.noovo.comport.server.ComService");
		intent.setAction("com.noovo.comport.server");
		mContext.startService(intent);
		try {
			Thread.sleep(500);
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		}
	}

	/**
	 * register the observer for the messages
	 */
	public void onResume() {
		mContext.getContentResolver().registerContentObserver(URI_RECEIVE, true, mComObserver);
	}

	/**
	 * unregister the observer for the messages
	 */
	public void onPause() {
		mContext.getContentResolver().unregisterContentObserver(mComObserver);
	}

	/**
	 * 
	 * @param port
	 *            value: 1, 2, 3, 4
	 * @param comName
	 *            set the name of the ComPort, such as "printer", "DVR" or any
	 *            string you like
	 * @param baudRate
	 *            set the baudrate of the
	 * @param databits
	 *            avalible values: 7 or 8
	 * @param stopbits
	 *            avalible values: 0 or 1
	 * @param parity
	 *            avalible values: 'N' 'n' 'E' 'e' 'O' 'o'        
	 */
	public void setCom(int port, String comName, int baudrate, int databits, int stopbits, char parity) {
		nameMap.put(comName, port);
		Uri uri = ContentUris.withAppendedId(URI_SET, port);
		ContentValues values = new ContentValues();
		values.put("name", comName);
		values.put("rate", baudrate);
		values.put("databits", databits);
		values.put("stopbits", stopbits);
		values.put("parity", String.valueOf(parity));
		mContext.getContentResolver().update(uri, values, null, null);
	}
	
	public void setCom(int port, String comName, int baudrate) {
		nameMap.put(comName, port);
		Uri uri = ContentUris.withAppendedId(URI_SET, port);
		ContentValues values = new ContentValues();
		values.put("name", comName);
		values.put("rate", baudrate);
		values.put("databits", 8);
		values.put("stopbits", 1);
		values.put("parity", String.valueOf('n'));
		mContext.getContentResolver().update(uri, values, null, null);
	}

	/**
	 * This message will be send once.
	 * 
	 * @param comName
	 * @param msg
	 */
	public void sendMessageOnce(String comName, byte[] msg) {
		if (nameMap.containsKey(comName)) {
			int port = nameMap.get(comName);
			Uri uri = ContentUris.withAppendedId(URI_SEND, port);
			ContentValues values = new ContentValues();
			values.put("msg", msg);
			values.put("loop", String.valueOf(false));
			values.put("send", String.valueOf(true));
			mContext.getContentResolver().update(uri, values, null, null);
		}
	}

	/**
	 * This message will be send
	 * 
	 * @param comName
	 * @param msg
	 * @param delay
	 */
	public void sendMessageLoop(String comName, byte[] msg, int delay) {
		if (nameMap.containsKey(comName)) {
			int port = nameMap.get(comName);
			Uri uri = ContentUris.withAppendedId(URI_SEND, port);
			ContentValues values = new ContentValues();
			values.put("msg", msg);
			values.put("loop", String.valueOf(true));
			values.put("delay", delay);
			values.put("send", String.valueOf(true));
			mContext.getContentResolver().update(uri, values, null, null);
		}
	}

	public void stopSendMessage(String comName) {
		if (nameMap.containsKey(comName)) {
			int port = nameMap.get(comName);
			Uri uri = ContentUris.withAppendedId(URI_SEND, port);
			ContentValues values = new ContentValues();
			values.put("send", String.valueOf(false));
			mContext.getContentResolver().update(uri, values, null, null);
		}
	}
}